package com.dudu.timer;

import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.mortbay.log.Log;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.dudu.access.RedisUtil;
import com.dudu.dao.AccountExtendDao;
import com.dudu.dao.PushNoticeInfoDao;
import com.dudu.dao.SendNoticeDao;
import com.dudu.enumeration.RedisKeyEnum;
import com.dudu.model.AccountExtend;
import com.dudu.model.SendNotice;
import com.dudu.utils.DateUtils;
import com.dudu.utils.EnumUtility;

import core.CoreDao;
import core.CoreDaoInvoke;

/**
 * 开始定时发送语音短信任务
 * 
 * @author gaoxs 2016-12-29
 * 
 * 
 */
@DisallowConcurrentExecution
public class SendVoiceNewJob implements org.quartz.StatefulJob {
    private CoreDao dao = CoreDaoInvoke.getInstance();
    private SendNoticeDao mSendNoticeDao = new SendNoticeDao();
    private PushNoticeInfoDao mPushNoticeInfoDao = new PushNoticeInfoDao();
    private AccountExtendDao accountExtendDao = new AccountExtendDao();
    private static String KEY_PREFIX = "voice:phone"; // 主键的前缀

    /**
     * 1、按计费账号 group by 并且获取总数A 2、使用Collections.sort方法进行排序（按从大到小）
     * 3、for(A)使用查询20以内 list.indexOf()查询位置+1=总数（Sub1） 4、计算平均值（P1）=300/总数（Sub1）
     * 5、for(A) 根据A.custAccount获取P1条待发送数据（B） 6、内循环for(B) 6.1、更新线程号 6.2、创建线程
     * 6.3、执行线程
     */
    public void execute(JobExecutionContext context) throws JobExecutionException {
	Log.debug("开始定时发送语音短信任务" + Thread.currentThread().getId());
	// 更新半小时还未执行完的线程号
	mSendNoticeDao.updateAllRunThread(dao);
	// 1、按计费账号 group by 并且获取总数A
	List<JSONObject> custList = mSendNoticeDao.queryCustAccountBySendNotice(dao);
	if (custList != null) {
	    // 2、使用Collections.sort方法进行排序（按从大到小）
	    Collections.sort(custList, new Comparator<Object>() {
		@Override
		public int compare(Object o1, Object o2) {
		    Integer count1 = ((JSONObject) o1).getInt("count");
		    Integer count2 = ((JSONObject) o2).getInt("count");
		    return count2.compareTo(count1);
		}
	    });
	    // 3、for(A) 查询20以内 list.indexOf()查询位置+1=总数（Sub1）
	    String limtCountStr = EnumUtility.getRedisValue(RedisKeyEnum.VOICELIMTCOUNT.getKey());
	    Integer limtCount = Integer.parseInt(limtCountStr);

	    int custCount = this.bigCustAccountCount(custList, limtCount);
	    // 4、计算平均值（P1）=300/总数（Sub1）
	    String threadCountStr = EnumUtility.getRedisValue(RedisKeyEnum.VOICETHREADAMOUNT.getKey());
	    Integer threadCount = Integer.parseInt(threadCountStr);

	    int p1 = threadCount / custCount + 30;
	    String timeStr = EnumUtility.getRedisValue(RedisKeyEnum.VOICEPHONETIME.getKey());
	    int time = Integer.parseInt(timeStr);
	    if (time < 5)
		time = 5;
	    // 5、for(A) 根据A.custAccount获取P1条待发送数据（B）
	    for (JSONObject json : custList) {
		String custAccount = json.getString("cust_account");
		AccountExtend custAccountBean = accountExtendDao.queryAccountExtendByCustAccount(dao, custAccount);
		List<SendNotice> sendNoticelist = mSendNoticeDao.querySendNoticeByCustAccount(dao, custAccount, p1);
		if (sendNoticelist != null) {
		    // 6、内循环for(B)
		    long threadid = System.currentTimeMillis();
		    for (SendNotice notice : sendNoticelist) {
			// 6.1、更新线程号
			if (custAccountBean.getFlag().equals("1")) {
			    notice.setRun_thread(threadid + "");
			    mSendNoticeDao.updateRunThread(dao, notice);
			    // 6.2、创建线程
			    SendVoiceThread sendVoiceThread = new SendVoiceThread(dao, notice, mPushNoticeInfoDao);
			    // 6.3、执行线程
			    sendVoiceThread.start();
			} else {
			    if (StringUtils.isBlank(RedisUtil.getString(KEY_PREFIX + notice.getCallee()))) {
				notice.setRun_thread(threadid + "");
				mSendNoticeDao.updateRunThread(dao, notice);
				// 6.2、创建线程
				SendVoiceThread sendVoiceThread = new SendVoiceThread(dao, notice, mPushNoticeInfoDao);
				// 6.3、执行线程
				sendVoiceThread.start();
				RedisUtil.setString(KEY_PREFIX + notice.getCallee(), time * 60, System.currentTimeMillis() + "");
			    } else {
				// 设置下次发起的时间，向后延时十分钟
				Date nowAdd = DateUtils.afterDate(new Date(), Calendar.MINUTE, time);// 获取当前时间+10分钟
				notice.setSchedule_send_time(DateUtils.getFormatTime(nowAdd, "yyyy-MM-dd HH:mm:ss"));
				// 更新下次发送时间(schedule_send_time)
				mSendNoticeDao.updateSendTime(dao, notice);
			    }
			}
		    }
		}
	    }
	}
    }

    /**
     * 3、for(A) 查询20以内 list.indexOf()查询位置+1=总数（Sub1）
     * 
     * @param custList
     * @param limtCount
     * @return
     */
    private int bigCustAccountCount(List<JSONObject> custList, int limtCount) {
	for (JSONObject json : custList) {
	    int s = json.getInt("count");
	    if (s < limtCount) {
		return custList.indexOf(json) + 1;
	    }
	}
	return custList.size() + 1;
    }

}
